<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<head>
  <meta charset="utf-8" />
  <meta name="generator" content="pandoc" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" />
  <title>Readme</title>
  <style>
    code{white-space: pre-wrap;}
    span.smallcaps{font-variant: small-caps;}
    span.underline{text-decoration: underline;}
    div.column{display: inline-block; vertical-align: top; width: 50%;}
    div.hanging-indent{margin-left: 1.5em; text-indent: -1.5em;}
    ul.task-list{list-style: none;}
    .display.math{display: block; text-align: center; margin: 0.5rem auto;}
  </style>
  <link rel="stylesheet" href="../../../../../_htmresc/mini-st_2020.css" />
  <!--[if lt IE 9]>
    <script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv-printshiv.min.js"></script>
  <![endif]-->
</head>
<body>
<div class="row">
<section id="nx_mqtt_client-application-description" class="col-sm-12 col-lg-8">
<h2><b>Nx_MQTT_Client application description</b></h2>
<p>This application provides an example of Azure RTOS NetX/NetXDuo stack usage . It shows how to exchange data between client and server using MQTT protocol in an encrypted mode supporting TLS v1.2.</p>
<p>The main entry function tx_application_define() is called by ThreadX during kernel start, at this stage, all NetX resources are created.</p>
<ul>
<li><p>A NX_PACKET_POOL is allocated</p></li>
<li><p>A NX_IP instance using that pool is initialized</p></li>
<li><p>The ARP, ICMP and protocols (TCP and UDP) are enabled for the NX_IP instance</p></li>
<li><p>A DHCP client is created.</p></li>
</ul>
<p>The application then creates 2 threads with different priorities:</p>
<ul>
<li><p><strong>AppMainThread</strong> (priority 10, PreemtionThreashold 10) : created with the TX_AUTO_START flag to start automatically.</p></li>
<li><p><strong>AppMQTTClientThread</strong> (priority 5, PreemtionThreashold 5) : created with the TX_DONT_START flag to be started later.</p></li>
</ul>
<p>The <strong>AppMainThread</strong> starts and perform the following actions:</p>
<ul>
<li><p>starts the DHCP client</p></li>
<li><p>waits for the IP address resolution</p></li>
<li><p>resumes the <strong>AppMQTTClientThread</strong></p></li>
</ul>
<p>The <strong>AppMQTTClientThread</strong>, once started:</p>
<ul>
<li><p>creates a dns_client with USER_DNS_ADDRESS used as DNS server then get MQTT broker address from MQTT_BROKER_NAME predefined on app_netxduo.h.</p></li>
<li><p>creates an mqtt_client</p></li>
<li><p>connects mqtt_client to the online MQTT broker; connection with server will be secure and a <strong>tls_setup_callback</strong> will set TLS parametres. By default MQTT_PORT for encrypted mode is 8883.</p>
<pre><code>  refer to note 4 below, to know how to setup an x509 certificate.</code></pre></li>
<li><p>mqtt_client subscribes on a predefined topic TOPIC_NAME “Temperature” with a Quality Of Service QOS0</p></li>
<li><p>depending on the number of message “NB_MESSAGE” defined by user, mqtt_client will publish a random number generated by RNG. If NB_MESSAGE = 0, it means that number of messages is infinitely.</p></li>
<li><p>mqtt_client will get messages from the MQTT broker and print them.</p></li>
</ul>
<h4 id="expected-success-behavior"><b> Expected success behavior</b></h4>
<ul>
<li>The board IP address is printed on the HyperTerminal</li>
<li>Connection’s information are printed on the HyperTerminal (broker’s name, mqtt port, topic and messages received)</li>
</ul>
<pre><code>MQTT client connected to broker &lt; test.mosquitto.org &gt; at PORT 8883 :
Message 1 received: TOPIC = Temperature, MESSAGE = 34
Message 2 received: TOPIC = Temperature, MESSAGE = 35
Message 3 received: TOPIC = Temperature, MESSAGE = 35
Message 4 received: TOPIC = Temperature, MESSAGE = 34
Message 5 received: TOPIC = Temperature, MESSAGE = 33
client disconnected from server</code></pre>
<ul>
<li>Green led is toggling after successfully receiving all messages.</li>
</ul>
<h4 id="error-behaviors"><b> Error behaviors</b></h4>
<ul>
<li>The red LED is toggling to indicate any error that has occurred.</li>
</ul>
<h4 id="assumptions-if-any"><b> Assumptions if any</b></h4>
<ul>
<li><p>The Application is using the DHCP to acquire IP address, thus a DHCP server should be reachable by the board in the LAN used to test the application.</p></li>
<li><p>The application is configuring the Ethernet IP with a static predefined MAC Address, make sure to change it in case multiple boards are connected on the same LAN to avoid any potential network traffic issues.</p></li>
<li><p>The MAC Address is defined in the <code>main.c</code></p></li>
</ul>
<pre><code>void MX_ETH_Init(void)
{

   /* USER CODE BEGIN ETH_Init 0 */

  /* USER CODE END ETH_Init 0 */

   static uint8_t MACAddr[6];

  /* USER CODE BEGIN ETH_Init 1 */

  /* USER CODE END ETH_Init 1 */
  heth.Instance = ETH;
  heth.Init.AutoNegotiation = ETH_AUTONEGOTIATION_ENABLE;
  heth.Init.Speed = ETH_SPEED_100M;
  heth.Init.DuplexMode = ETH_MODE_FULLDUPLEX;
  heth.Init.PhyAddress = LAN8742A_PHY_ADDRESS;
  MACAddr[0] = 0x00;
  MACAddr[1] = 0x80;
  MACAddr[2] = 0xE1;
  MACAddr[3] = 0x00;
  MACAddr[4] = 0x00;
  MACAddr[5] = 0x00;</code></pre>
<h4 id="known-limitations"><b>Known limitations</b></h4>
<ul>
<li><p>Default NX_DNS_MAX_RETRIES value in “nx_user.h” may not work with some MQTT servers, they should be tuned for example:</p>
<p>#define NX_DNS_MAX_RETRIES 10</p></li>
<li><p>Since NetXDuo does not support proxy, mqtt_client should be connected directly to the server.</p></li>
</ul>
<h3 id="notes"><b>Notes</b></h3>
<ol type="1">
<li>To make an encrypted connection with MQTT server, user should follow these steps to add an x509 certificate to the <em>mqtt_client</em> and use it to ensure server’s authentication :
<ul>
<li><p>download certificate authority CA (in this application “mosquitto.org.der” downloaded from <a href="https://test.mosquitto.org">test.mosquitto</a></p></li>
<li><p>convert certificate downloaded by executing the following cmd from the file downloaded path :</p>
<pre><code>            xxd.exe -i mosquitto.org.der &gt; mosquitto.cert.h</code></pre></li>
<li><p>add the converted file under the application : NetXDuo/Nx_MQTT_Client/NetXDuo/App</p></li>
<li><p>configure MOSQUITTO_CERT_FILE with your certificate name.</p></li>
</ul></li>
</ol>
<h4 id="threadx-usage-hints"><b>ThreadX usage hints</b></h4>
<ul>
<li>ThreadX uses the Systick as time base, thus it is mandatory that the HAL uses a separate time base through the TIM IPs.</li>
<li>ThreadX is configured with 100 ticks/sec by default, this should be taken into account when using delays or timeouts at application. It is always possible to reconfigure it in the “tx_user.h”, the “TX_TIMER_TICKS_PER_SECOND” define,but this should be reflected in “tx_initialize_low_level.s” file too.</li>
<li>ThreadX is disabling all interrupts during kernel start-up to avoid any unexpected behavior, therefore all system related calls (HAL, BSP) should be done either at the beginning of the application or inside the thread entry functions.</li>
<li>ThreadX offers the “tx_application_define()” function, that is automatically called by the tx_kernel_enter() API. It is highly recommended to use it to create all applications ThreadX related resources (threads, semaphores, memory pools…) but it should not in any way contain a system API call (HAL or BSP).</li>
<li>Using dynamic memory allocation requires to apply some changes to the linker file. ThreadX needs to pass a pointer to the first free memory location in RAM to the tx_application_define() function, using the “first_unused_memory” argument. This require changes in the linker files to expose this memory location.
<ul>
<li>For EWARM add the following section into the .icf file:</li>
</ul>
<pre><code>place in RAM_region    { last section FREE_MEM };</code></pre>
<ul>
<li>For MDK-ARM:</li>
</ul>
<pre><code>either define the RW_IRAM1 region in the &quot;.sct&quot; file
or modify the line below in &quot;tx_low_level_initilize.s to match the memory region being used
    LDR r1, =|Image$$RW_IRAM1$$ZI$$Limit|</code></pre>
<ul>
<li>For STM32CubeIDE add the following section into the .ld file:</li>
</ul>
<pre><code>._threadx_heap :
  {
     . = ALIGN(8);
     __RAM_segment_used_end__ = .;
     . = . + 64K;
     . = ALIGN(8);
   } &gt;RAM_D1 AT&gt; RAM_D1</code></pre>
<pre><code>The simplest way to provide memory for ThreadX is to define a new section, see ._threadx_heap above.
In the example above the ThreadX heap size is set to 64KBytes.
The ._threadx_heap must be located between the .bss and the ._user_heap_stack sections in the linker script.  
Caution: Make sure that ThreadX does not need more than the provided heap memory (64KBytes in this example).  
Read more in STM32CubeIDE User Guide, chapter: &quot;Linker script&quot;.</code></pre>
<ul>
<li>The “tx_initialize_low_level.s” should be also modified to enable the “USE_DYNAMIC_MEMORY_ALLOCATION” flag.</li>
</ul></li>
</ul>
<h3 id="keywords"><b>Keywords</b></h3>
<p>RTOS, Network, ThreadX, NetXDuo, MQTT, TLS, UART</p>
<h3 id="hardware-and-software-environment"><b>Hardware and Software environment</b></h3>
<ul>
<li><p>This application runs on STM32F429xx devices</p></li>
<li><p>This application has been tested with STMicroelectronics STM32F429ZI Nucleo boards Revision MB1137 B-01 and can be easily tailored to any other supported device and development board.</p></li>
<li><p>This application uses USART3 to display logs, the hyperterminal configuration is as follows:</p>
<ul>
<li>BaudRate = 115200 baud</li>
<li>Word Length = 8 Bits</li>
<li>Stop Bit = 1</li>
<li>Parity = none</li>
<li>Flow control = None</li>
</ul></li>
</ul>
<h3 id="how-to-use-it"><b>How to use it ?</b></h3>
<p>In order to make the program work, you must do the following :</p>
<ul>
<li>Open your preferred toolchain</li>
<li>Edit the file app_netxduo.h : define the USER_DNS_ADDRESS, the MQTT_BROKER_NAME and NB_MESSAGE.</li>
<li>Rebuild all files and load your image into target memory</li>
<li>Run the application<br />
</li>
</ul>
</section>
</div>
</body>
</html>
